feat(Query): query complexity framework with sorting examples#401
feat(Query): query complexity framework with sorting examples#401kim-em wants to merge 3 commits intoleanprover:mainfrom
Conversation
dc724df to
8371c12
Compare
| /- | ||
| Copyright (c) 2026 Lean FRO, LLC. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Sorrachai Yingchareonthawornchai, Kim Morrison, Sebastian Graf, Shreyas Srinivas |
There was a problem hiding this comment.
Sorrachai is not an author on this file, only on the TimeM files. Further on all prog files I am first author
8371c12 to
dbb9e41
Compare
Add a framework for proving upper and lower bounds on query complexity of comparison-based algorithms, using `Prog` (free monad over query types) with oracle-parametric evaluation and structural query counting. Results: - Insertion sort: correctness + O(n²) upper bound - Merge sort: correctness + n·⌈log₂ n⌉ upper bound - Lower bound: any correct comparison sort on an infinite type needs ≥ ⌈log₂(n!)⌉ queries (via adversarial pigeonhole on QueryTree depth) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dbb9e41 to
9acdbbd
Compare
Add `Prog.cost`, a weighted generalization of `Prog.queriesOn` where each query type can have a different cost. Demonstrate this with complex multiplication: naive (4 muls + 2 adds) vs Gauss's trick (3 muls + 5 adds), proving correctness, exact parametric costs, and the crossover condition. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| Authors: Kim Morrison | ||
| -/ | ||
| module | ||
|
|
There was a problem hiding this comment.
This is the Arith Prog from my CslibTests files?
Shreyas4991
left a comment
There was a problem hiding this comment.
Thus arith query is similar to mine in the the CslibTests folder
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shreyas4991
left a comment
There was a problem hiding this comment.
A non-comprehensive comparison with previous PR and authorship issues that arise therein.
| namespace Cslib.Query | ||
|
|
||
| /-- Insert `x` into a sorted list using comparison queries. -/ | ||
| @[expose] def orderedInsert (x : α) : List α → Prog (LEQuery α) (List α) |
There was a problem hiding this comment.
This is identical to the Prog version upto query type.
|
|
||
| -- ## Query count proofs | ||
|
|
||
| theorem orderedInsert_queriesOn_le (oracle : {ι : Type} → LEQuery α ι → ι) |
There was a problem hiding this comment.
You oracle is just my Model.evalQuery. Likewise for time.
| toQTOracle (fromQTOracle f) = f := rfl | ||
|
|
||
| /-- Convert a `Prog (LEQuery α)` program to a `QueryTree (α × α) Bool` decision tree. -/ | ||
| @[expose] def Prog.toQueryTree : Prog (LEQuery α) β → QueryTree (α × α) Bool β |
There was a problem hiding this comment.
This is essentially traceSort from cslib#372
| /- | ||
| Copyright (c) 2026 Lean FRO, LLC. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Sorrachai Yingchareonthawornchai, Kim Morrison |
There was a problem hiding this comment.
The authorship claims on this go to an equal extent for me and Sorrachai. We both use a different recursive structure and I provide the Prog version of his code. Since the recursion structure is different here (and more akin to the upstream version), potentially neither of us are co-authors or both of us are.
| @@ -0,0 +1,107 @@ | |||
| /- | |||
| Copyright (c) 2026 Lean FRO, LLC. All rights reserved. | |||
| Released under Apache 2.0 license as described in the file LICENSE. | |||
There was a problem hiding this comment.
I published a similar proof of model wide lower bound a few hours before cslib#376 got there.
| /-- Evaluate a program by answering each query using `oracle`. -/ | ||
| @[expose] def eval (oracle : {ι : Type} → Q ι → ι) : Prog Q α → α | ||
| | .pure a => a | ||
| | .liftBind op cont => eval oracle (cont (oracle op)) |
There was a problem hiding this comment.
I claim that pattern matching on the free monad is exploiting an implementation detail, and that everything should really go through the universal property, FreeM.liftM. (this is what #372 does)
| namespace Cslib.Query | ||
|
|
||
| /-- Arithmetic queries: addition, subtraction, and multiplication. -/ | ||
| inductive ArithQuery (α : Type) : Type → Type where |
There was a problem hiding this comment.
You want a zero or one for completeness. Also if it is just an illustrative example, it belongs in the tests folder (see my PR).
This PR implements Sebastian Graf's unified approach to query complexity (discussed in the CSLib Algorithm frameworks thread), combining the strengths of #372 (explicit
Prog/FreeMquery types) and #376 (monad-parametric approach).Programs are
Prog Q α(free monad over query typeQ), and the oracle is supplied after the program produces its query plan — giving anti-cheating guarantees for both upper and lower bounds. No WP/Hoare triple machinery is needed: correctness is just equations aboutProg.eval oracle, and cost is just equations aboutProg.queriesOn oracle.This provides an alternative to the
TimeM-based cost analysis already in the repo: here query counting is structural (derived from theProgtree) rather than annotation-based.New files
Query/Prog.leanProgtype,eval,queriesOn, simp lemmasQuery/Bounds.leanUpperBoundandLowerBounddefinitionsQuery/QueryTree.leanQuery/Sort/LEQuery.leanQuery/Sort/IsSort.leanIsSortcorrectness specificationQuery/Sort/Insertion/{Defs,Lemmas}.leanQuery/Sort/Merge/{Defs,Lemmas}.leanQuery/Sort/QueryTree.leanProg-to-QueryTreebridge + pigeonhole depth lemmaQuery/Sort/LowerBound.leanResults
IsSortinstanceIsSortinstanceIsSorton an infinite type makes ≥ ⌈log₂(n!)⌉ queries. The proof constructs n! distinct total orders via permutations of embedded elements, shows they force distinct sorted outputs, then applies an adversarial pigeonhole argument onQueryTreedepth.🤖 Prepared with Claude Code